package yawning.mew.sim;

import java.util.Map;

import yawning.mew.ProcEffect;
import yawning.mew.ProcEffect.Effect;

public class SimulationProc extends SimulationEvent {
	ProcEffect mEffect;
	private double mIcdExpireTime;
	public int nrStacks = 0;
	
	public interface EffectCallback {
		public void onEffect(int n);
	}
	
	public SimulationProc(SimulationEngine su, ProcEffect effect) {
		super(su);
		mEffect = effect;
		if (mEffect.buffStackMax < 1) mEffect.buffStackMax = 1;
	}
	
	public void onProc() {
		if (mIcdExpireTime > mSimUtil.getSimTime()) return;
		if (mEffect.rate > 0 && !mSimUtil.getRandom().nextBoolean(mEffect.rate)) return;
		if (mEffect.ppm > 0 && !mSimUtil.getRandom().nextBoolean((1.0/60) * mEffect.ppm)) return; 
		
		// Called when a proc is triggered.  Cooldown checking done elsewhere.
		if (mEffect.buffCooldown > 0) mIcdExpireTime = mSimUtil.getSimTime() + mEffect.buffCooldown;

		// Only want to increment stats if the buff won't be a refresh.
		if (nrStacks < mEffect.buffStackMax) {
			for (Map.Entry<Effect,Integer> e : mEffect.mEffects.entrySet()) {
				mSimUtil.mEffectCallbacks.get(e.getKey()).onEffect(e.getValue());
			}
			nrStacks++;
		}
		schedule(mEffect.buffDuration);
	}

	@Override
	public void onExpire() {
		for (Map.Entry<Effect,Integer> e : mEffect.mEffects.entrySet()) {
			mSimUtil.mEffectCallbacks.get(e.getKey()).onEffect(- e.getValue() * nrStacks);
		}
		nrStacks = 0;
	}
	
	public ProcEffect getProcEffect() {
		return mEffect;
	}
}
